<script setup lang="ts">
import { Edit, Search, SuccessFilled, Avatar } from '@element-plus/icons-vue'
import { nextTick, ref, unref, watch } from 'vue'
import { useBaseApi } from '@/api/base'
import { isArray, toArrayTree } from 'xe-utils'
import { ElMessage } from 'element-plus'
import type { SubType } from '@/types/custom'

interface Props {
  title: string
}

withDefaults(defineProps<Props>(), {
  title: '表单'
})

const emit = defineEmits(['fetch', 'change'])

const { GetSubList } = useBaseApi()

const treeRef = ref()
const checkedKey = ref('')
const search = ref('')
const showCheckbox = ref(true)
const loading = ref(false)
const dialogVisible = ref(false)
const tableData = ref<any[]>([])
const checked = ref<string[]>([])

/**
 * 打开
 * @param check 多选
 * @param ids
 */
const open = (check: boolean, ids?: string[] | string) => {
  showCheckbox.value = check
  dialogVisible.value = true
  if (isArray(ids)) {
    checked.value = ids || []
  } else {
    checkedKey.value = ids || ''
  }
  nextTick(initData)
}

/**
 * 初始化数据
 */
const initData = async () => {
  if (!tableData.value.length) {
    await onFetch()
  }
  if (showCheckbox.value) setCheckedKeys()
}

/**
 * 设置用户
 */
const setCheckedKeys = () => {
  nextTick(() => {
    treeRef.value!.setCheckedKeys(unref(checked), false)
  })
}

/**
 * 查询
 */
const onFetch = async () => {
  return GetSubList().then(({ data }) => {
    const parent: SubType = {
      id: 'ALL',
      name: '',
      sort: 0,
      sequence: '',
      created_on: '',
      value: 'ALL',
      label: '全部'
    }
    data.forEach((dep) => {
      if (!dep.pid) {
        dep.pid = parent.id
      }
      dep.value = dep.id
      dep.label = dep.name
    })
    data.push(parent)
    tableData.value = toArrayTree(data, { parentKey: 'pid' })
    setCheckedKeys()
  })
}

/**
 * 提交
 */
const submitForm = () => {
  if (showCheckbox.value) {
    emit('change', checked.value)
  } else {
    if (checkedKey.value) {
      emit('change', checkedKey.value)
      dialogVisible.value = false
    } else {
      ElMessage.warning('请选择用户')
      return
    }
  }
  dialogVisible.value = false
}

watch(search, (val) => {
  treeRef.value!.filter(val)
})

const filterNode = (value: string, data: TypedAny) => {
  if (!value) return true
  return data.label.includes(value)
}

/**
 * 复选框
 */
const onCheckChange = () => {
  if (showCheckbox.value) {
    checked.value = treeRef.value!.getCheckedKeys(true)
  }
}

/**
 * 节点
 */
const onCheckNodeClick = () => {
  if (!showCheckbox.value) {
    const node = treeRef.value!.getCurrentNode()
    if (node.isUser) {
      checkedKey.value = node.id
    }
  }
}

defineExpose({ open })
</script>

<template>
  <el-dialog v-model="dialogVisible" :title="title" append-to-body>
    <div class="pb10 flex align-center justify-between">
      <el-input
        v-model="search"
        style="width: 250px"
        placeholder="搜索全表"
        clearable
        :prefix-icon="Search"
      />
      <span>已选用户：{{ checkedKey ? 1 : checked.length }}</span>
    </div>
    <el-scrollbar style="height: 70vh">
      <el-tree
        ref="treeRef"
        :data="tableData"
        :show-checkbox="showCheckbox"
        node-key="id"
        :props="{
          children: 'children',
          label: 'label'
        }"
        highlight-current
        default-expand-all
        :filter-node-method="filterNode"
        @check="onCheckChange"
        @node-click="onCheckNodeClick"
      >
        <template #default="{ node, data }">
          <span
            v-if="data.isUser"
            class="flex align-center"
            :class="{ 'color-primary': checkedKey === data.id }"
          >
            <el-icon v-if="checkedKey === data.id"><SuccessFilled /></el-icon>
            <el-icon v-else><Avatar /></el-icon>
            <span class="ml5">{{ node.label }}</span>
          </span>
        </template>
      </el-tree>
    </el-scrollbar>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogVisible = false" :loading="loading">取消</el-button>
        <el-button type="primary" @click="submitForm" :loading="loading" :icon="Edit">
          确认
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>
